package org.road0329.dlt698;

import java.nio.ByteBuffer;

public class DataUtils {
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

    public static void readFully(ReverseByteArrayInputStream input, byte[] buffer, int off, int len) throws Exception {
        do {
            int bytesRead = input.readoffset(buffer, off, len);
            if (bytesRead == -1) {
                throw new Exception("Unexpected end of input stream.");
            }
            len -= bytesRead;
            off += bytesRead;
        } while (len > 0);
    }

    public static byte[] toBytes(String value) throws Exception {
        if (value == null || value.trim().length() <= 0) {
            throw new Exception("value is null or value.length = 0");
        }
        value = value.trim();
        if (value.length() % 2 != 0) {
            throw new Exception("value.length % 2 != 0");
        }
        byte[] ret = new byte[value.length() / 2];
        for (int i = 0; i < ret.length; i++) {
            try {
                String tmp = value.substring(i * 2, i * 2 + 2);
                ret[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
            } catch (NumberFormatException e) {
                throw new Exception("cast exception");
            }
        }
        return ret;
    }

    public static byte[] hexToBytes(String hex) throws Exception {
        if (hex.length() < 1) {
            throw new Exception("hex is null or empty");
        } else {
            byte[] result = new byte[hex.length() / 2];
            int j = 0;
            for (int i = 0; i < hex.length(); i += 2) {
                result[j++] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
            }
            return result;
        }
    }

    public static String intToHexString(int value, int bytesLength) {
        if (bytesLength != 1 && bytesLength != 2 && bytesLength != 4) {
            return null;
        }
        int mask = 0;
        switch (bytesLength) {
            case 1:
                mask = 0x000000FF;
                break;
            case 2:
                mask = 0x0000FFFF;
                break;
            case 4:
                mask = 0xFFFFFFFF;
                break;
        }
        int length = 2 * bytesLength;
        String ret = Integer.toHexString(value & mask);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < (length - ret.length()); i++) {
            sb.append("0");
        }
        sb.append(ret);
        return sb.toString();
    }

    public static String bytesToHexString(byte[] buf) {
        return bytesToHexString(buf, 0, buf.length);
    }

    public static String bytesToHexString(byte[] buf, int offset, int length) {
        if (buf == null || offset < 0 || length < 0 || offset + length > buf.length) {
            return null;
        }
        StringBuilder retBuffer = new StringBuilder();
        for (int i = offset; i < offset + length; i++) {
            retBuffer.append(byteToHexToString(buf[i]));
        }
        return retBuffer.toString().toUpperCase();
    }

    public static String byteToHexToString(byte value) {
        String tmp = Integer.toHexString(value & 0xFF);
        tmp = tmp.toUpperCase();
        return tmp.length() % 2 == 1 ? "0" + tmp : tmp;
    }

    public static String toHexString(byte[] buf, int bytesLength, int length) throws Exception {
        if ((bytesLength != 1) && (bytesLength != 2) && (bytesLength != 4)) {
            throw new Exception("bytesLength not 1，2，4");
        }
        StringBuilder sb = new StringBuilder();
        for (int i = length; i < buf.length; i++) {
            int mask = 0;
            switch (bytesLength) {
                case 1:
                    mask = 255;
                    break;
                case 2:
                    mask = 65535;
                    break;
                case 4:
                    mask = -1;
            }
            int actualLength = 2 * bytesLength;
            int b = buf[i] & mask;
            String ret = Integer.toHexString(b);
            for (int j = 0; j < actualLength - ret.length(); j++) {
                sb.append("0");
            }
            sb.append(ret);
        }
        return sb.toString().toUpperCase();
    }

    public static int digit(int codePoint, int radix) {
        if (radix < 2 || radix > 36) {
            return -1;
        }
        if (codePoint < 128) {
            // Optimized for ASCII
            int result = -1;
            if ('0' <= codePoint && codePoint <= '9') {
                result = codePoint - '0';
            } else if ('a' <= codePoint && codePoint <= 'z') {
                result = 10 + (codePoint - 'a');
            } else if ('A' <= codePoint && codePoint <= 'Z') {
                result = 10 + (codePoint - 'A');
            }
            return result < radix ? result : -1;
        }
        return -1;
    }

    public static String toShortHexString(byte[] bytes, int offset, int length, boolean revert) {
        char[] hexChars = new char[length * 2];
        for (int j = offset; j < offset + length; j++) {
            int v = bytes[j] & 0xFF;
            if (revert) {
                hexChars[(length * 2 - (j - offset) * 2 - 2)] = HEX_ARRAY[(v >>> 4)];
                hexChars[(length * 2 - (j - offset) * 2 - 1)] = HEX_ARRAY[(v & 0xF)];
            } else {
                hexChars[((j - offset) * 2)] = HEX_ARRAY[(v >>> 4)];
                hexChars[((j - offset) * 2 + 1)] = HEX_ARRAY[(v & 0xF)];
            }
        }
        return new String(hexChars);
    }

    public static byte[] fromShortHexString(String str, boolean revert) throws Exception {
        if (str == null) {
            throw new Exception("string s may not be null");
        }
        str = str.trim();
        str = str.replace(" ", "");
        if ((str.length() == 0) || ((str.length() % 2) != 0)) {
            throw new Exception("string is not a legal hex string.");
        }
        int length = str.length();
        byte[] data = new byte[length / 2];
        for (int i = 0; i < length; i += 2) {
            int firstCharacter = digit(str.charAt(i), 16);
            int secondCharacter = digit(str.charAt(i + 1), 16);
            if ((firstCharacter == -1) || (secondCharacter == -1)) {
                throw new Exception("string is not a legal hex string.");
            }
            if (revert) {
                data[((length - i) / 2 - 1)] = (byte) (((firstCharacter << 4) + secondCharacter));
            } else {
                data[(i / 2)] = (byte) (((firstCharacter << 4) + secondCharacter));
            }
        }
        return data;
    }

    public static void main(String[] args) {
        System.out.println(DataUtils.intToHexString(0, 1));
    }
}



